import asyncio
# -*- coding: utf-8 -*-
"""
Agent系统核心模块

本模块定义了多Agent架构的核心组件：
- BaseAgent: Agent基类，定义通用接口和基础功能
- Agent管理和路由功能
- 多Agent协作检测
- 人工确认机制

具体的Agent实现应该继承BaseAgent类并实现相应的业务逻辑。
演示Agent实现请参考demo_agents.py文件。
"""

import json
import uuid
from abc import ABC, abstractmethod
from typing import Dict, List, Any, Optional, AsyncGenerator
from datetime import datetime, timedelta
from models import (
    AgentConfig, WorkflowState, WorkflowStatus, SessionContext,
    ChartData, FormData, FormField, ConfirmationRequest
)
from llm_service import llm_service
from data_sources import data_source_service
import logging

# 日志记录器
logger = logging.getLogger(__name__)

class BaseAgent(ABC):
    """
    Agent基类
    
    定义了所有Agent的通用接口和基础功能。
    所有具体的Agent都必须继承此类并实现process方法。
    """
    
    def __init__(self, config: AgentConfig):
        """
        初始化Agent
        
        Args:
            config: Agent配置对象，包含名称、描述、关键词等信息
        """
        self.config = config
        self.name = config.name                    # Agent名称
        self.description = config.description      # Agent描述
        self.keywords = config.keywords            # 关键词列表（用于意图匹配）
        self.data_sources = config.data_sources    # 支持的数据源
        self.output_types = config.output_types    # 支持的输出类型
        self.priority = config.priority            # 优先级（数值越高优先级越高）
    
    @abstractmethod
    async def process(
        self,
        query: str,
        context: SessionContext,
        workflow_state: Optional[WorkflowState] = None
    ) -> AsyncGenerator[Dict[str, Any], None]:
        """
        处理用户查询（抽象方法）
        
        每个具体的Agent都必须实现此方法来处理用户查询。
        支持流式输出，可以逐步返回处理结果。
        
        Args:
            query: 用户查询文本
            context: 会话上下文，包含用户信息、租户信息等
            workflow_state: 工作流状态（可选），用于多步骤处理
            
        Yields:
            Dict[str, Any]: 处理结果，包含类型和数据
        """
        pass
    
    def match_intent(self, query: str, extracted_entities: Dict[str, Any]) -> float:
        """
        计算意图匹配度
        
        根据查询文本和提取的实体计算当前Agent处理该查询的匹配度。
        匹配度用于Agent选择和路由。
        
        Args:
            query: 用户查询文本
            extracted_entities: 提取的实体信息
            
        Returns:
            float: 匹配度分数（0.0-1.0），越高表示越匹配
        """
        score = 0.0
        query_lower = query.lower()
        
        # 关键词匹配（每个匹配的关键词加0.3分）
        for keyword in self.keywords:
            if keyword.lower() in query_lower:
                score += 0.3
        
        # 实体匹配（有实体信息加0.2分，具体Agent可以重写此逻辑）
        if extracted_entities:
            score += 0.2
        
        # 确保分数不超过1.0
        return min(score, 1.0)

# ============================================================================
# Agent注册和管理功能
# ============================================================================

# 具体的Agent实现已移至demo_agents.py文件
# 在实际业务开发中，请根据需要创建具体的Agent类继承BaseAgent

# 导入演示Agent
try:
    from demo_agents import DEMO_AGENT_REGISTRY
    # Agent注册表 - 集成演示Agent
    AGENT_REGISTRY = DEMO_AGENT_REGISTRY.copy()
except ImportError:
    logger.warning("无法导入demo_agents模块，使用空的Agent注册表")
    AGENT_REGISTRY = {}


def get_available_agents() -> List[str]:
    """
    获取所有可用的Agent列表
    
    Returns:
        List[str]: Agent名称列表
    """
    return list(AGENT_REGISTRY.keys())


def get_agent(agent_name: str) -> Optional[BaseAgent]:
    """
    根据名称获取Agent实例
    
    Args:
        agent_name: Agent名称
        
    Returns:
        Optional[BaseAgent]: Agent实例，如果不存在则返回None
    """
    return AGENT_REGISTRY.get(agent_name)


def detect_multi_agent_requirement(query: str) -> bool:
    """
    检测查询是否需要多Agent协作
    
    通过关键词分析判断是否需要多个Agent协同处理。
    
    Args:
        query: 用户查询文本
        
    Returns:
        bool: 是否需要多Agent协作
    """
    multi_agent_keywords = [
        "同时", "并且", "还要", "另外", "以及",
        "分析并", "查询并", "创建并", "生成并"
    ]
    
    return any(keyword in query for keyword in multi_agent_keywords)


def requires_human_confirmation(query: str, agent_names: List[str]) -> bool:
    """
    判断是否需要人工确认
    
    对于高风险操作或涉及多个Agent的复杂任务，
    需要人工确认后再执行。
    
    Args:
        query: 用户查询文本
        agent_names: 涉及的Agent名称列表
        
    Returns:
        bool: 是否需要人工确认
    """
    # 高风险关键词
    high_risk_keywords = [
        "删除", "清空", "重置", "批量", "全部",
        "永久", "不可恢复", "强制"
    ]
    
    # 多Agent协作通常需要确认
    if len(agent_names) > 1:
        return True
    
    # 包含高风险关键词需要确认
    if any(keyword in query for keyword in high_risk_keywords):
        return True
    
    return False